
import java.io.File;

public class Align {

	SequenceAligner aligner;

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		if (args.length < 4) {
			System.out.println("sequencesFile matrixFile h g");
			System.exit(0);
		}

		Align align = new Align();
		if (align.init(args[0], args[1], args[2], args[3])) {
			align.align();
			align.outputAlignment();
		}

	}

	public Align() {
	}

	protected boolean init(String seqFilePath, String matrixFilePath,
			String hVal, String gVal) {
		File seqFile = new File(seqFilePath);
		File matrixFile = new File(matrixFilePath);
		int h = new Integer(hVal).intValue();
		int g = new Integer(gVal).intValue();

		boolean valid = true;
		String message = "";

		if (!seqFile.canRead()) {
			message = message + "Can not read from sequence file \n";
			valid = false;
		}

		if (!matrixFile.canRead()) {
			message = message + "Can not read from substitution matrix file \n";
			valid = false;
		}

		if (!valid) {
			System.out.println(message);
			return false;
		}

		AlignmentStrings seqStrs = new AlignmentStrings();
		try {
			seqStrs.setFile(seqFile);
		} catch (Exception e) {
			System.out.println("Fail to init sequences");
			return false;
		}

		SubstitutionMatrix subMatrix = new SubstitutionMatrix();
		try {
			subMatrix.setFile(matrixFile);
		} catch (Exception e) {
			System.out.println("Fail to init substitution matrix");
			return false;
		}

		SubMatrixAlignScore subMatrixAlgnScore = new SubMatrixAlignScore();
		subMatrixAlgnScore.setStr1(seqStrs.string1);
		subMatrixAlgnScore.setStr2(seqStrs.string2);
		subMatrixAlgnScore.setSubMatrix(subMatrix);

		GapPenalty lnrGP = new AffineGapPenalty(h, g);
		aligner = new AffineGPLocalAligner();
		aligner.setSequences(seqStrs.string1, seqStrs.string2);
		aligner.setAlignmentScoreFunction(subMatrixAlgnScore);
		aligner.setGapPenaltyFunction(lnrGP);
		return aligner.init();
	}

	protected boolean align() {
		aligner.align();
		aligner.traceBack();
		return true;
	}

	protected void outputAlignment() {
		System.out.println(aligner.getAlignedStr1());
		System.out.println();
		System.out.println(aligner.getAlignedStr2());
	}

}
